package tw.right929.utils
{
	import flash.utils.Dictionary;

	/**
	 * 全靜態類別，用來處理陣列。
	 * 所有傳入的參數物件必需下述條件其中之一，才能正常的運作。
	 * 1.必需有length屬性，能用[]運算子配合index取出物件。
	 * 2.有unique方法，其傳回不重覆項目陣列。
	 */
	public class ArrayUtil
	{
		/**
		 * 把所有ArrayUtil中的方法，混入傳入的obj之中。
		 */
		public static function mixin(obj:*):void
		{
			if(!obj.hasOwnProperty("unique"))
				obj["unique"]	=	uniqueF;
			obj["union"]	=	unionF;
			obj["intersect"]	=	intersectF;
			obj["isInclude"]	=	isIncludeF;
			obj["difference"]	=	differenceF;
		}
		
		/**
		 * 消除陣列中的重覆項目。
		 */
		public static function unique(arr:*):Array
		{
			if(arr.hasOwnProperty("unique"))
				return arr.unique();
			
			var map:Dictionary	=	new Dictionary(true);
			for(var i:int=0 ; i<arr.length ; i++)
				map[arr[i]]	=	i;
			
			var temp:Array	=	new Array();
			for(var p:* in map)
				temp.push(p);
			
			return temp;
		}
		/**
		 * 消除陣列中的重覆項目。(mixin專用)
		 */
		public static var uniqueF:Function	=	function ():Array
		{
			return ArrayUtil.unique(this);
		};
		
		/**
		 * 傳回二個陣列間的聯集，會消除重覆的項目。
		 */
		public static function union(arr1:* , arr2:*):Array
		{
			arr1	=	ArrayUtil.unique(arr1);
			arr2	=	ArrayUtil.unique(arr2);
			return ArrayUtil.unique(arr1.concat(arr2));
		}
		/**
		 * 傳回二個陣列間的聯集，會消除重覆的項目。(mixin專用)
		 */
		public static var unionF:Function	=	function (arr:*):Array
		{
			return ArrayUtil.union(this , arr);
		};
		
		/**
		 * 傳回二個陣列間的交集，會消除重覆的項目。
		 */
		public static function intersect(arr1:* , arr2:*):Array
		{
			arr1	=	ArrayUtil.unique(arr1);
			arr2	=	ArrayUtil.unique(arr2);
			
			if(arr1.length > arr2.length)
				return _intersect(arr1 , arr2);
			else
				return _intersect(arr2 , arr1);
		}
		private static function _intersect(arr1:Array , arr2:Array):Array
		{
			var temp:Array	=	new Array();
			for(var j:int=0 ; j<arr1.length ; j++)
			{
				for(var i:int=0 ; i<arr2.length ; i++)
				{
					if(arr1[j] == arr2[i])
					{
						temp.push(arr1[j]);
						arr2.splice(i , 1);
						break;
					}
				}
			}
			return temp;	
		}
		/**
		 * 傳回二個陣列間的交集，會消除重覆的項目。(mixin專用)
		 */
		public static var intersectF:Function	=	function (arr:*):Array
		{
			return ArrayUtil.intersect(this , arr);
		};
			
		
		/**
		 * 陣列1是否包含了陣列2的所有物件，會消除重覆的項目。
		 */
		public static function isInclude(arr1:* , arr2:*):Boolean
		{
			arr1	=	ArrayUtil.unique(arr1);
			arr2	=	ArrayUtil.unique(arr2);
			
			if(arr2.length > arr1.length)
				return false;
			return intersect(arr1 , arr2).length == arr2.length;
		}
		/**
		 * 陣列是否包含了傳入陣列的所有物件，會消除重覆的項目。(mixin專用)
		 */
		public static var isIncludeF:Function	=	function (arr:*):Boolean
		{
			return ArrayUtil.isInclude(this , arr);
		};
		
		/**
		 * 陣列1和陣列2的差(陣列1中有但陣列2中沒有的)，會消除重覆的項目。
		 */
		public static function difference(arr1:* , arr2:*):Array
		{
			arr1	=	ArrayUtil.unique(arr1);
			arr2	=	ArrayUtil.unique(arr2);
			
			for(var j:int=0 ; j<arr2.length ; j++)
			{
				for(var i:int=0 ; i<arr1.length ; i++)
				{
					if(arr2[j] == arr1[i])
					{
						arr1.splice(i , 1);
						break;
					}
				}
			}
			return arr1;	
		}
		/**
		 * 陣列1和陣列2的差(陣列1中有但陣列2中沒有的)，會消除重覆的項目。(mixin專用)
		 */
		public static var differenceF:Function	=	function (arr:*):Array
		{
			return ArrayUtil.difference(this , arr);
		};
	}
}